﻿using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace Tsanie.ShellExt.Definitions
{
    public class FileCollection : ReadOnlyCollectionBase, IDisposable
    {

        #region - APIs -

        [DllImport("shell32.dll", CharSet = CharSet.Ansi, EntryPoint = "DragQueryFileA")]
        extern static int DragQueryFile(IntPtr hDrop, int iFile, [MarshalAs(UnmanagedType.LPStr)] StringBuilder lpszFile, int cch);
        [DllImport("ole32.dll")]
        extern static int ReleaseStgMedium(ref STGMEDIUM Stm);

        #endregion

        #region - Collection Members -

        public FileCollection(IDataObject Data)
        {
            if (Data == null)
            {
                return;
            }
            FORMATETC FMT = default(FORMATETC);
            STGMEDIUM STM = default(STGMEDIUM);
            FMT.cfFormat = 15;  // CF_HDROP
            FMT.tymed = TYMED.TYMED_HGLOBAL;
            FMT.dwAspect = DVASPECT.DVASPECT_CONTENT;

            try
            {
                Data.GetData(ref FMT, out STM);
                int max = DragQueryFile(STM.unionmember, -1, null, 0);
#if DEBUGFC
                Common.OutputDebugString("FileCollection(IDataObject):: File count = {0}", max);
#endif
                for (int id = 0; id < max; id++)
                {
                    StringBuilder file = new StringBuilder(512);
                    DragQueryFile(STM.unionmember, id, file, file.Capacity);
                    InnerList.Add(file.ToString());
#if DEBUGFC
                    Common.OutputDebugString("FileCollection(IDataObject):: Files[{0}] = {1}", id, file);
#endif
                }
            }
            catch (Exception e)
            {
                Common.OutputError("FileCollection(IDataObject)", e);
            }
            finally
            {
                ReleaseStgMedium(ref STM);
            }
        }

        public string this[int index] { get { return InnerList[index].ToString(); } }
        public void CopyTo(string[] array, int index) { base.InnerList.CopyTo(array, index); }

        #endregion

        #region - IDisposable 成员 -

        public void Dispose()
        {
            InnerList.Clear();
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
